home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 301-325 / disk_319 / cnewssrc / cnews.src.lzh / relay / trbatch.c < prev    next >
C/C++ Source or Header  |  1989-06-17  |  4KB  |  194 lines

  1. /* 
  2.  * transmit batch file management
  3.  */
  4. #include <stdio.h>
  5. #include <sys/types.h>
  6. #include "libc.h"
  7. #include "news.h"
  8. #include "msgs.h"
  9. #include "trbatch.h"
  10.  
  11. /* tunable parameters */
  12. #ifndef FLUSHEVERY
  13. #define FLUSHEVERY 1    /* fflush batch files every this many lines */
  14. #endif            /* FLUSHEVERY */
  15. #ifndef NOPENBFS
  16. #define NOPENBFS 10    /* # batchfiles kept open for batching (arbitrary) */
  17. #endif            /* NOPENBFS */
  18.  
  19. static struct batchfile batchfile[NOPENBFS];    /* try to keep open always */
  20. #define lastbf &batchfile[NOPENBFS-1]
  21. /*
  22.  * More than one pointer in ordtobfs may point at a given batchfile,
  23.  * to permit sharing of open batch files among multiple sys entries.
  24.  * ordtobfs[ordinal # of batch sys entry] -> (usually open) batch file,
  25.  * if the index is in range.
  26.  */
  27. static struct batchfile *ordtobfs[NOPENBFS];
  28. static struct batchfile fakebatf;    /* for non-cached batch files */
  29.  
  30. /* forwards */
  31. FORWARD statust bfclose(), bfrclose();
  32. FORWARD struct batchfile *bfincache(), *fakebf();
  33.  
  34. /*
  35.  * open "name" for appending, for batch sys entry with ordinal # "ord".
  36.  *
  37.  * if ord is too big, see if any batchfile has been assigned to "name" yet;
  38.  * if not, set up a fake batchfile for temporary use.  if ord is in range,
  39.  * ensure that (name, ord) are mapped to a batchfile.
  40.  *
  41.  * if an attempt to open the batchfile's stream fails, close a random
  42.  * batchfile stream and retry the open.
  43.  */
  44. struct batchfile *
  45. bfopen(name, ord)
  46. register char *name;
  47. register int ord;
  48. {
  49.     register struct batchfile *bf;
  50.  
  51.     if (ord >= NOPENBFS) {            /* no mapping possible */
  52.         bf = bfisopen(name);
  53.         if (bf == NULL)
  54.             bf = fakebf((FILE *)NULL, name);
  55.     } else
  56.         bf = bfincache(name, ord);
  57.  
  58.     if (bf->bf_str == NULL)
  59.         bf->bf_str = fopenclex(name, "a");
  60.     if (bf->bf_str == NULL) {
  61.         if (bfrclose() != ST_OKAY)
  62.             return NULL;
  63.         bf->bf_str = fopenwclex(name, "a");    /* retry, may bitch */
  64.     }
  65.     return bf;
  66. }
  67.  
  68. /*
  69.  * returns a batchfile, never NULL, corresponding to name and ord.
  70.  * if ord isn't mapped, search the batchfile cache for name;
  71.  * if missing, initialise batchfile[ord] and map ord to it.
  72.  * if ord wasn't mapped, but name was in the cache, map ord to the cache hit.
  73.  */
  74. STATIC struct batchfile *
  75. bfincache(name, ord)
  76. char *name;
  77. int ord;
  78. {
  79.     register struct batchfile *bf = ordtobfs[ord];
  80.  
  81.     if (bf == NULL) {
  82.         bf = bfisopen(name);
  83.         if (bf == NULL) {
  84.             /* establish new mapping for a new file */
  85.             bf = &batchfile[ord];
  86.             bf->bf_name = strsave(name);
  87.             bf->bf_str = NULL;    /* paranoia */
  88. #ifdef notdef
  89.             bf->bf_ref = 0;
  90. #endif
  91.             bf->bf_lines = FLUSHEVERY;
  92.         }
  93.         ordtobfs[ord] = bf;
  94.     }
  95.     /* mapping is now set (ord -> bf) */
  96.     return bf;
  97. }
  98.  
  99. statust
  100. bffkclose(ord)                /* close ord's batchfile, if fake */
  101. int ord;
  102. {
  103.     register statust status = ST_OKAY;
  104.  
  105.     if (ord >= NOPENBFS)
  106.         status |= bfclose(&fakebatf);
  107.     return status;
  108. }
  109.  
  110. STATIC statust
  111. bfclose(bf)
  112. register struct batchfile *bf;
  113. {
  114.     register statust status = ST_OKAY;
  115.  
  116.     if (nfclose(bf->bf_str) == EOF)
  117.         status = prfulldisk(bf->bf_name);
  118.     bf->bf_str = NULL;    /* prevent accidents; mark as closed */
  119.     return status;
  120. }
  121.  
  122. STATIC struct batchfile *
  123. fakebf(stream, name)
  124. FILE *stream;
  125. char *name;
  126. {
  127.     fakebatf.bf_name = name;
  128.     fakebatf.bf_str = stream;
  129.     return &fakebatf;
  130. }
  131.  
  132. /*
  133.  * search the batchfile cache for "name"; return the hit, if any.
  134.  */
  135. struct batchfile *
  136. bfisopen(name)
  137. register char *name;
  138. {
  139.     register struct batchfile *bf;
  140.  
  141.     for (bf = batchfile; bf <= lastbf; bf++)
  142.         if (bf->bf_name != NULL && STREQ(name, bf->bf_name))
  143.             return bf;
  144.     return NULL;
  145. }
  146.  
  147. /*
  148.  * a performance hack: only fflush bf->bf_str every FLUSHEVERY calls.
  149.  */
  150. int
  151. bfflush(bf)
  152. register struct batchfile *bf;
  153. {
  154.     register int ret = 0;
  155.  
  156.     if (--bf->bf_lines <= 0) {
  157.         bf->bf_lines = FLUSHEVERY;
  158.         ret = fflush(bf->bf_str);
  159.     }
  160.     return ret;
  161. }
  162.  
  163. STATIC statust
  164. bfrclose()                /* close a random batchfile */
  165. {
  166.     register struct batchfile *bf;
  167.     register statust status = ST_OKAY;
  168.  
  169.     for (bf = batchfile; bf <= lastbf; bf++)
  170.         if (bf->bf_str != NULL) {
  171.             status |= bfclose(bf);
  172.             break;
  173.         }
  174.     return status;
  175. }
  176.  
  177. statust
  178. bfrealclose()                /* close all open batch files */
  179. {
  180.     register struct batchfile *bf;
  181.     register statust status = ST_OKAY;
  182.  
  183.     for (bf = batchfile; bf <= lastbf; bf++) {
  184.         if (bf->bf_str != NULL)        /* batch file stream open */
  185.             status |= bfclose(bf);
  186.         nnfree(&bf->bf_name);
  187. #ifdef notdef
  188.         bf->bf_ref = 0;
  189. #endif
  190.         ordtobfs[bf - batchfile] = NULL;    /* unmap batch file */
  191.     }
  192.     return status;
  193. }
  194.